#
# Try to find CUDA compiler, runtime libraries, and include path.
# Once done this will define
#
# CUDA_FOUND
# CUDA_INCLUDE_PATH
# CUDA_RUNTIME_LIBRARY
# CUDA_COMPILER
#
# It will also define the following macro:
#
# WRAP_CUDA
#

IF (WIN32)
	FIND_PROGRAM (CUDA_COMPILER nvcc.exe
		$ENV{CUDA_BIN_PATH}
		DOC "The CUDA Compiler")
ELSE(WIN32)
	FIND_PROGRAM (CUDA_COMPILER nvcc
		$ENV{CUDA_BIN_PATH}
		/usr/local/cuda/bin
		DOC "The CUDA Compiler")
ENDIF(WIN32)

IF (CUDA_COMPILER)
	GET_FILENAME_COMPONENT (CUDA_COMPILER_DIR ${CUDA_COMPILER} PATH)
	GET_FILENAME_COMPONENT (CUDA_COMPILER_SUPER_DIR ${CUDA_COMPILER_DIR} PATH)
ELSE (CUDA_COMPILER)
	SET (CUDA_COMPILER_DIR .)
	SET (CUDA_COMPILER_SUPER_DIR ..)
ENDIF (CUDA_COMPILER)

FIND_PATH (CUDA_INCLUDE_PATH cuda_runtime.h
	$ENV{CUDA_INC_PATH}
	${CUDA_COMPILER_SUPER_DIR}/include
	DOC "The directory where CUDA headers reside")

FIND_PATH (CUTIL_INCLUDE_PATH cutil.h
	"$ENV{NVSDKCUDA_ROOT}/common/inc"
	"$ENV{PROGRAMFILES}/NVIDIA Corporation/NVIDIA CUDA SDK/common/inc"
	DOC "The directory where the CUTIL headers reside")

FIND_LIBRARY (CUDA_RUNTIME_LIBRARY
	NAMES cudart
	PATHS
	$ENV{CUDA_LIB_PATH}
	${CUDA_COMPILER_SUPER_DIR}/lib
	${CUDA_COMPILER_DIR}
	DOC "The CUDA runtime library")

FIND_LIBRARY (CUTIL_LIBRARY
	NAMES cutil32 cutil64
	PATHS
	"$ENV{NVSDKCUDA_ROOT}/common/lib"
	"$ENV{PROGRAMFILES}/NVIDIA Corporation/NVIDIA CUDA SDK/common/lib"
	DOC "The CUTIL library")

IF (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)
	SET (CUDA_FOUND TRUE)
ELSE (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)
	SET (CUDA_FOUND FALSE)
ENDIF (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)

SET (CUDA_LIBRARIES ${CUDA_RUNTIME_LIBRARY})

MARK_AS_ADVANCED (CUDA_FOUND CUDA_COMPILER CUDA_RUNTIME_LIBRARY)


IF (CUTIL_INCLUDE_PATH AND CUTIL_LIBRARY)
	SET (CUTIL_FOUND 1 CACHE STRING "Set to 1 if CUDA is found, 0 otherwise")
ELSE (CUTIL_INCLUDE_PATH AND CUTIL_LIBRARY)
	SET (CUTIL_FOUND 0 CACHE STRING "Set to 1 if CUDA is found, 0 otherwise")
ENDIF (CUTIL_INCLUDE_PATH AND CUTIL_LIBRARY)

SET (CUTIL_LIBRARIES ${CUTIL_LIBRARY})

MARK_AS_ADVANCED (CUTIL_FOUND)


#SET(CUDA_OPTIONS "-ncfe")
SET(CUDA_OPTIONS "--host-compilation=C++")

IF (CUDA_EMULATION)
	SET (CUDA_OPTIONS "${CUDA_OPTIONS} -deviceemu")
ENDIF (CUDA_EMULATION)


# Get include directories.
MACRO(GET_CUDA_INC_DIRS _cuda_INC_DIRS)
	SET(${_cuda_INC_DIRS})
	GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)

	FOREACH(_current ${_inc_DIRS})
		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${_current})
	ENDFOREACH(_current ${_inc_DIRS})
	
	SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CUDA_INCLUDE_PATH})

#	IF (CMAKE_SYTEM_INCLUDE_PATH)
#		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CMAKE_SYSTEM_INCLUDE_PATH})
#	ENDIF (CMAKE_SYTEM_INCLUDE_PATH)
#	IF (CMAKE_INCLUDE_PATH)
#		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CMAKE_INCLUDE_PATH})
#	ENDIF (CMAKE_INCLUDE_PATH)

ENDMACRO(GET_CUDA_INC_DIRS)


# Get file dependencies.
MACRO (GET_CUFILE_DEPENDENCIES dependencies file)
	GET_FILENAME_COMPONENT(filepath ${file} PATH)
	
	#  parse file for dependencies
	FILE(READ "${file}" CONTENTS)
	#STRING(REGEX MATCHALL "#[ \t]*include[ \t]+[<\"][^>\"]*" DEPS "${CONTENTS}")
	STRING(REGEX MATCHALL "#[ \t]*include[ \t]+\"[^\"]*" DEPS "${CONTENTS}")
	
	SET(${dependencies})
	
	FOREACH(DEP ${DEPS})
		STRING(REGEX REPLACE "#[ \t]*include[ \t]+\"" "" DEP "${DEP}")

		FIND_PATH(PATH_OF_${DEP} ${DEP}
			${filepath})

		IF(NOT ${PATH_OF_${DEP}} STREQUAL PATH_OF_${DEP}-NOTFOUND)
			#MESSAGE("${file} : ${PATH_OF_${DEP}}/${DEP}")
			SET(${dependencies} ${${dependencies}} ${PATH_OF_${DEP}}/${DEP})
		ENDIF(NOT ${PATH_OF_${DEP}} STREQUAL PATH_OF_${DEP}-NOTFOUND)
		
	ENDFOREACH(DEP)

ENDMACRO (GET_CUFILE_DEPENDENCIES)


# WRAP_CUDA(outfile ...)
MACRO (WRAP_CUDA outfiles)
	GET_CUDA_INC_DIRS(cuda_includes)
	#MESSAGE(${cuda_includes})

	FOREACH (CUFILE ${ARGN})
		GET_FILENAME_COMPONENT (CUFILE ${CUFILE} ABSOLUTE)
		GET_FILENAME_COMPONENT (CPPFILE ${CUFILE} NAME_WE)
		SET (CPPFILE ${CMAKE_CURRENT_BINARY_DIR}/${CPPFILE}.gen.cpp)

		GET_CUFILE_DEPENDENCIES(CUDEPS ${CUFILE})
		#MESSAGE("${CUDEPS}")

		ADD_CUSTOM_COMMAND (
			OUTPUT ${CPPFILE}
			COMMAND ${CUDA_COMPILER}
			ARGS -cuda ${cuda_includes} ${CUDA_OPTIONS} -o ${CPPFILE} ${CUFILE}
			MAIN_DEPENDENCY ${CUFILE}
			DEPENDS ${CUDEPS})

		#MACRO_ADD_FILE_DEPENDENCIES(${CUFILE} ${CPPFILE})

		SET (${outfiles} ${${outfiles}} ${CPPFILE})
	ENDFOREACH (CUFILE)
	
	SET_SOURCE_FILES_PROPERTIES(${outfiles} PROPERTIES GENERATED 1)
	
ENDMACRO (WRAP_CUDA)
